# -*- coding: utf-8 -*-
# @Time    : 2021/5/27 20:59
# @Author  : YIGE
# @Email   : yige@maqu.com
# @File    : verifyUtil.py
# @Software: PyCharm
import string, random, os

from utils.resFormatUtil import ResFormat
from PIL import Image, ImageFont, ImageDraw, ImageFilter


def verifyParam(*param):  # 接收装饰器传入的参数
    """
    参数验证装饰器
    :param param:要验证的参数
    :return:
    """

    def verify(fun):
        def isNone(request, *args, **kwargs):
            # 根据请求方式获取请求参数
            request_param = getattr(request, request.method)  # 反射

            # 循环获取要校验的参数
            for i in param:
                value = request_param.get(i, None)
                if not value:
                    return ResFormat(status='PARAM_ERROR').json_response()

            return fun(request, *args, **kwargs)  # 回调

        return isNone

    return verify


# 图像验证码类
class ImageVerify:
    def __init__(self, width=140, height=40, length=4, size=28):
        """
        初始化
        :param width: 验证码图片宽度
        :param height: 验证码图片高度
        :param length: 验证码内字符的长度
        :param size: 验证码内字符的大小
        """
        self.width = width
        self.height = height
        self.length = length
        self.size = size

    def random_str(self):
        """
        随机生成验证码图片内的字符（验证码图片答案）
        26个大小写字母和10个数字为源进行组合
        :return:
        """
        source = string.ascii_letters + ''.join([str(i) for i in range(10)])
        return ''.join(random.sample(source, self.length))  # 从source中随机获取self.length个字符

    def random_color(self, start=0, end=255):
        """
        随机RGB颜色
        :param start: 起始值
        :param end: 结束值
        :return: tuple (R,G,B) 颜色值
        """
        res = (random.randint(start, end) for i in range(3))
        return tuple(res)

    def random_lines(self, draw):
        """
        绘制干扰线
        :param draw:
        :return:
        """
        for i in range(self.length):
            lines = [(random.randint(0, self.width), random.randint(0, self.height)) for i in range(2)]
            draw.line(list(lines), fill=self.random_color(65, 255), width=2)

    def random_points(self, draw, rate):
        """
        绘制噪点
        :param draw: draw对象
        :param rate: 噪点频率
        :return:
        """
        for x in range(self.width):
            for y in range(self.height):
                if random.randint(1, 100) <= rate:  # 概率控制
                    draw.point((x, y), fill=self.random_color(65, 255))

    def veri_code(self):
        """
        生成验证码图片
        :return:
        """
        # 创建Image对象
        image = Image.new('RGB', (self.width, self.height), (255, 255, 255))

        # 创建Font对象
        file = os.path.dirname(os.path.abspath(__file__))
        font = ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf', self.size)

        # 创建Draw对象
        draw = ImageDraw.Draw(image)

        self.random_lines(draw)
        self.random_points(draw, 40)

        # 验证码字符
        code = self.random_str()

        # 随机颜色写到图片
        for t in range(self.length):
            draw.text((35 * t + 5, 3), code[t], font=font, fill=self.random_color(35, 125))

        # 增加模糊滤镜
        image = image.filter(ImageFilter.BLUR)
        return image, code


if __name__ == '__main__':
    imageVerify = ImageVerify()
    img, code = imageVerify.veri_code()
    with open('test.png', 'wb') as f:
        img.save(f)
    print(code)
